home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / r_draw.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  24KB  |  1,072 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    The actual span/column drawing functions.
  21. //    Here find the main potential for optimization,
  22. //     e.g. inline assembly, different algorithms.
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
  29.  
  30.  
  31. #include "doomdef.h"
  32.  
  33. #include "i_system.h"
  34. #include "z_zone.h"
  35. #include "w_wad.h"
  36.  
  37. #include "r_local.h"
  38.  
  39. // Needs access to LFB (guess what).
  40. #include "v_video.h"
  41.  
  42. // State.
  43. #include "doomstat.h"
  44.  
  45.  
  46. // ?
  47. #define MAXWIDTH            1120
  48. #define MAXHEIGHT            832
  49.  
  50. // status bar height at bottom of screen
  51. #define SBARHEIGHT        32
  52.  
  53. //
  54. // All drawing to the view buffer is accomplished in this file.
  55. // The other refresh files only know about ccordinates,
  56. //  not the architecture of the frame buffer.
  57. // Conveniently, the frame buffer is a linear one,
  58. //  and we need only the base address,
  59. //  and the total size == width*height*depth/8.,
  60. //
  61.  
  62.  
  63. byte*        viewimage; 
  64. int        viewwidth;
  65. int        scaledviewwidth;
  66. int        viewheight;
  67. int        viewwindowx;
  68. int        viewwindowy; 
  69. byte*        ylookup[MAXHEIGHT]; 
  70. int        columnofs[MAXWIDTH]; 
  71.  
  72. // Color tables for different players,
  73. //  translate a limited part to another
  74. //  (color ramps used for  suit colors).
  75. //
  76. FAR byte    translations[3][256];    
  77.  
  78.  
  79.  
  80.  
  81. //
  82. // R_DrawColumn
  83. // Source is the top of the column to scale.
  84. //
  85. lighttable_t*        dc_colormap; 
  86. int            dc_x; 
  87. int            dc_yl; 
  88. int            dc_yh; 
  89. fixed_t            dc_iscale; 
  90. fixed_t            dc_texturemid;
  91.  
  92. // first pixel in a column (possibly virtual) 
  93. byte*            dc_source;        
  94.  
  95. // just for profiling 
  96. int            dccount;
  97.  
  98. //
  99. // A column is a vertical slice/span from a wall texture that,
  100. //  given the DOOM style restrictions on the view orientation,
  101. //  will always have constant z depth.
  102. // Thus a special case loop for very fast rendering can
  103. //  be used. It has also been used with Wolfenstein 3D.
  104. // 
  105. // UNUSED.
  106. #ifndef AMIGA
  107. void R_DrawColumn (void) 
  108.     int            count; 
  109.     byte*        dest; 
  110.     fixed_t        frac;
  111.     fixed_t        fracstep;     
  112.  
  113.     count = dc_yh - dc_yl; 
  114.  
  115.     // Zero length, column does not exceed a pixel.
  116.     if (count < 0) 
  117.     return; 
  118.                  
  119. #ifdef RANGECHECK 
  120.     if ((unsigned)dc_x >= SCREENWIDTH
  121.     || dc_yl < 0
  122.     || dc_yh >= SCREENHEIGHT) 
  123.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); 
  124. #endif 
  125.  
  126.     // Framebuffer destination address.
  127.     // Use ylookup LUT to avoid multiply with ScreenWidth.
  128.     // Use columnofs LUT for subwindows? 
  129.     dest = ylookup[dc_yl] + columnofs[dc_x];  
  130.  
  131.     // Determine scaling,
  132.     //  which is the only mapping to be done.
  133.     fracstep = dc_iscale; 
  134.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  135.  
  136.     // Inner loop that does the actual texture mapping,
  137.     //  e.g. a DDA-lile scaling.
  138.     // This is as fast as it gets.
  139.     do 
  140.     {
  141.     // Re-map color indices from wall texture column
  142.     //  using a lighting/special effects LUT.
  143.     *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  144.     
  145.     dest += SCREENWIDTH; 
  146.     frac += fracstep;
  147.     
  148.     } while (count--); 
  149. #endif
  150.  
  151.  
  152.  
  153. // UNUSED.
  154. // Loop unrolled.
  155. #if 0
  156. void R_DrawColumn (void) 
  157.     int            count; 
  158.     byte*        source;
  159.     byte*        dest;
  160.     byte*        colormap;
  161.     
  162.     unsigned        frac;
  163.     unsigned        fracstep;
  164.     unsigned        fracstep2;
  165.     unsigned        fracstep3;
  166.     unsigned        fracstep4;     
  167.  
  168.     count = dc_yh - dc_yl + 1; 
  169.  
  170.     source = dc_source;
  171.     colormap = dc_colormap;         
  172.     dest = ylookup[dc_yl] + columnofs[dc_x];  
  173.      
  174.     fracstep = dc_iscale<<9; 
  175.     frac = (dc_texturemid + (dc_yl-centery)*dc_iscale)<<9; 
  176.  
  177.     fracstep2 = fracstep+fracstep;
  178.     fracstep3 = fracstep2+fracstep;
  179.     fracstep4 = fracstep3+fracstep;
  180.     
  181.     while (count >= 8) 
  182.     { 
  183.     dest[0] = colormap[source[frac>>25]]; 
  184.     dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; 
  185.     dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; 
  186.     dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]];
  187.     
  188.     frac += fracstep4; 
  189.  
  190.     dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; 
  191.     dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; 
  192.     dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; 
  193.     dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]]; 
  194.  
  195.     frac += fracstep4; 
  196.     dest += SCREENWIDTH*8; 
  197.     count -= 8;
  198.     } 
  199.     
  200.     while (count > 0)
  201.     { 
  202.     *dest = colormap[source[frac>>25]]; 
  203.     dest += SCREENWIDTH; 
  204.     frac += fracstep; 
  205.     count--;
  206.     } 
  207. }
  208. #endif
  209.  
  210.  
  211. #ifndef AMIGA
  212. void R_DrawColumnLow (void) 
  213.     int            count; 
  214.     byte*        dest; 
  215.     byte*        dest2;
  216.     fixed_t        frac;
  217.     fixed_t        fracstep;     
  218.  
  219.     count = dc_yh - dc_yl; 
  220.  
  221.     // Zero length.
  222.     if (count < 0) 
  223.     return; 
  224.                  
  225. #ifdef RANGECHECK 
  226.     if ((unsigned)dc_x >= SCREENWIDTH
  227.     || dc_yl < 0
  228.     || dc_yh >= SCREENHEIGHT)
  229.     {
  230.     
  231.     I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
  232.     }
  233.     //    dccount++; 
  234. #endif 
  235.     // Blocky mode, need to multiply by 2.
  236.     dc_x <<= 1;
  237.     
  238.     dest = ylookup[dc_yl] + columnofs[dc_x];
  239.     dest2 = ylookup[dc_yl] + columnofs[dc_x+1];
  240.     
  241.     fracstep = dc_iscale; 
  242.     frac = dc_texturemid + (dc_yl-centery)*fracstep;
  243.     
  244.     do 
  245.     {
  246.     // Hack. Does not work corretly.
  247.     *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
  248.     dest += SCREENWIDTH;
  249.     dest2 += SCREENWIDTH;
  250.     frac += fracstep; 
  251.  
  252.     } while (count--);
  253. }
  254. #endif
  255.  
  256.  
  257. //
  258. // Spectre/Invisibility.
  259. //
  260. #ifndef AMIGA
  261. #define FUZZTABLE       50 
  262. #else
  263. #define FUZZTABLE       250
  264. #endif
  265. #define FUZZOFF    (SCREENWIDTH)
  266.  
  267.  
  268. int    fuzzoffset[FUZZTABLE] =
  269. {
  270.     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  271.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  272.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  273.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  274.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  275.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  276.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF 
  277. #ifdef AMIGA
  278.     ,FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  279.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  280.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  281.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  282.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  283.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  284.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,
  285.     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  286.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  287.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  288.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  289.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  290.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  291.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,
  292.     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  293.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  294.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  295.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  296.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  297.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  298.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,
  299.     FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  300.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  301.     FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,
  302.     FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,
  303.     FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
  304.     FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
  305.     FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
  306. #endif
  307. }; 
  308.  
  309.  
  310. int    fuzzpos = 0; 
  311.  
  312.  
  313. #ifndef AMIGA
  314.  
  315. //
  316. // Framebuffer postprocessing.
  317. // Creates a fuzzy image by copying pixels
  318. //  from adjacent ones to left and right.
  319. // Used with an all black colormap, this
  320. //  could create the SHADOW effect,
  321. //  i.e. spectres and invisible players.
  322. //
  323. void R_DrawFuzzColumn (void) 
  324.     int            count; 
  325.     byte*        dest; 
  326.     fixed_t        frac;
  327.     fixed_t        fracstep;     
  328.  
  329.     // Adjust borders. Low... 
  330.     if (!dc_yl) 
  331.     dc_yl = 1;
  332.  
  333.     // .. and high.
  334.     if (dc_yh == viewheight-1) 
  335.     dc_yh = viewheight - 2; 
  336.          
  337.     count = dc_yh - dc_yl; 
  338.  
  339.     // Zero length.
  340.     if (count < 0) 
  341.     return; 
  342.  
  343.     
  344. #ifdef RANGECHECK 
  345.     if ((unsigned)dc_x >= SCREENWIDTH
  346.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  347.     {
  348.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  349.          dc_yl, dc_yh, dc_x);
  350.     }
  351. #endif
  352.  
  353.  
  354.     // Keep till detailshift bug in blocky mode fixed,
  355.     //  or blocky mode removed.
  356.     /* WATCOM code 
  357.     if (detailshift)
  358.     {
  359.     if (dc_x & 1)
  360.     {
  361.         outpw (GC_INDEX,GC_READMAP+(2<<8) ); 
  362.         outp (SC_INDEX+1,12); 
  363.     }
  364.     else
  365.     {
  366.         outpw (GC_INDEX,GC_READMAP); 
  367.         outp (SC_INDEX+1,3); 
  368.     }
  369.     dest = destview + dc_yl*80 + (dc_x>>1); 
  370.     }
  371.     else
  372.     {
  373.     outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); 
  374.     outp (SC_INDEX+1,1<<(dc_x&3)); 
  375.     dest = destview + dc_yl*80 + (dc_x>>2); 
  376.     }*/
  377.  
  378.     
  379.     // Does not work with blocky mode.
  380.     dest = ylookup[dc_yl] + columnofs[dc_x];
  381.  
  382.     // Looks familiar.
  383.     fracstep = dc_iscale; 
  384.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  385.  
  386.     // Looks like an attempt at dithering,
  387.     //  using the colormap #6 (of 0-31, a bit
  388.     //  brighter than average).
  389.     do 
  390.     {
  391.     // Lookup framebuffer, and retrieve
  392.     //  a pixel that is either one column
  393.     //  left or right of the current one.
  394.     // Add index from colormap to index.
  395.     *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; 
  396.  
  397.     // Clamp table lookup index.
  398.     if (++fuzzpos == FUZZTABLE) 
  399.         fuzzpos = 0;
  400.     
  401.     dest += SCREENWIDTH;
  402.  
  403.     frac += fracstep; 
  404.     } while (count--); 
  405. #endif
  406.  
  407.   
  408.  
  409.  
  410. #ifndef AMIGA
  411.  
  412. //
  413. // Framebuffer postprocessing.
  414. // Creates a fuzzy image by copying pixels
  415. //  from adjacent ones to left and right.
  416. // Used with an all black colormap, this
  417. //  could create the SHADOW effect,
  418. //  i.e. spectres and invisible players.
  419. //
  420. void R_DrawFuzzColumnLow (void) 
  421.     int            count; 
  422.     byte*        dest; 
  423.     byte*        dest2; 
  424.     fixed_t        frac;
  425.     fixed_t        fracstep;     
  426.  
  427.     // Adjust borders. Low... 
  428.     if (!dc_yl) 
  429.     dc_yl = 1;
  430.  
  431.     // .. and high.
  432.     if (dc_yh == viewheight-1) 
  433.     dc_yh = viewheight - 2; 
  434.          
  435.     count = dc_yh - dc_yl; 
  436.  
  437.     // Zero length.
  438.     if (count < 0) 
  439.     return; 
  440.  
  441.     
  442. #ifdef RANGECHECK 
  443.     if (((unsigned)dc_x << 1) >= SCREENWIDTH
  444.     || dc_yl < 0 || dc_yh >= SCREENHEIGHT)
  445.     {
  446.     I_Error ("R_DrawFuzzColumn: %i to %i at %i",
  447.          dc_yl, dc_yh, dc_x);
  448.     }
  449. #endif
  450.  
  451.  
  452.     // Does not work with blocky mode.
  453.     dest = ylookup[dc_yl] + columnofs[dc_x << 1];
  454.     dest2 = ylookup[dc_yl] + columnofs[(dc_x << 1) + 1];
  455.  
  456.     // Looks familiar.
  457.     fracstep = dc_iscale;
  458.     frac = dc_texturemid + (dc_yl-centery)*fracstep;
  459.  
  460.     // Looks like an attempt at dithering,
  461.     //  using the colormap #6 (of 0-31, a bit
  462.     //  brighter than average).
  463.     do 
  464.     {
  465.     // Lookup framebuffer, and retrieve
  466.     //  a pixel that is either one column
  467.     //  left or right of the current one.
  468.     // Add index from colormap to index.
  469.     *dest2 = *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]];
  470.  
  471.     // Clamp table lookup index.
  472.     if (++fuzzpos == FUZZTABLE)
  473.         fuzzpos = 0;
  474.  
  475.     dest += SCREENWIDTH;
  476.     dest2 += SCREENWIDTH;
  477.  
  478.     frac += fracstep;
  479.     } while (count--);
  480. }
  481. #endif
  482.  
  483.   
  484.  
  485.  
  486. //
  487. // R_DrawTranslatedColumn
  488. // Used to draw player sprites
  489. //  with the green colorramp mapped to others.
  490. // Could be used with different translation
  491. //  tables, e.g. the lighter colored version
  492. //  of the BaronOfHell, the HellKnight, uses
  493. //  identical sprites, kinda brightened up.
  494. //
  495. byte*    dc_translation;
  496. byte*    translationtables;
  497.  
  498. //#ifndef AMIGA
  499.  
  500. void R_DrawTranslatedColumn (void) 
  501.     int            count; 
  502.     byte*        dest; 
  503.     fixed_t        frac;
  504.     fixed_t        fracstep;     
  505.  
  506.     count = dc_yh - dc_yl; 
  507.     if (count < 0) 
  508.     return; 
  509.                  
  510. #ifdef RANGECHECK 
  511.     if ((unsigned)dc_x >= SCREENWIDTH
  512.     || dc_yl < 0
  513.     || dc_yh >= SCREENHEIGHT)
  514.     {
  515.     I_Error ( "R_DrawColumn: %i to %i at %i",
  516.           dc_yl, dc_yh, dc_x);
  517.     }
  518.     
  519. #endif 
  520.  
  521.  
  522.     // WATCOM VGA specific.
  523.     /* Keep for fixing.
  524.     if (detailshift)
  525.     {
  526.     if (dc_x & 1)
  527.         outp (SC_INDEX+1,12); 
  528.     else
  529.         outp (SC_INDEX+1,3);
  530.     
  531.     dest = destview + dc_yl*80 + (dc_x>>1); 
  532.     }
  533.     else
  534.     {
  535.     outp (SC_INDEX+1,1<<(dc_x&3)); 
  536.  
  537.     dest = destview + dc_yl*80 + (dc_x>>2); 
  538.     }*/
  539.  
  540.     
  541.     // FIXME. As above.
  542.     dest = ylookup[dc_yl] + columnofs[dc_x]; 
  543.  
  544.     // Looks familiar.
  545.     fracstep = dc_iscale; 
  546.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  547.  
  548.     // Here we do an additional index re-mapping.
  549.     do 
  550.     {
  551.     // Translation tables are used
  552.     //  to map certain colorramps to other ones,
  553.     //  used with PLAY sprites.
  554.     // Thus the "green" ramp of the player 0 sprite
  555.     //  is mapped to gray, red, black/indigo. 
  556.     *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  557.     dest += SCREENWIDTH;
  558.     
  559.     frac += fracstep; 
  560.     } while (count--); 
  561.  
  562. //#endif
  563.  
  564.  
  565.  
  566. //
  567. // R_DrawTranslatedColumn
  568. // Used to draw player sprites
  569. //  with the green colorramp mapped to others.
  570. // Could be used with different translation
  571. //  tables, e.g. the lighter colored version
  572. //  of the BaronOfHell, the HellKnight, uses
  573. //  identical sprites, kinda brightened up.
  574. //
  575. byte*    dc_translation;
  576. byte*    translationtables;
  577.  
  578. //#ifndef AMIGA
  579.  
  580. void R_DrawTranslatedColumnLow (void) 
  581.     int            count; 
  582.     byte*        dest; 
  583.     byte*        dest2;
  584.     fixed_t        frac;
  585.     fixed_t        fracstep;     
  586.  
  587.     count = dc_yh - dc_yl; 
  588.     if (count < 0) 
  589.     return; 
  590.                  
  591. #ifdef RANGECHECK 
  592.     if (((unsigned)dc_x << 1) >= SCREENWIDTH
  593.     || dc_yl < 0
  594.     || dc_yh >= SCREENHEIGHT)
  595.     {
  596.     I_Error ( "R_DrawColumn: %i to %i at %i",
  597.           dc_yl, dc_yh, dc_x);
  598.     }
  599.     
  600. #endif 
  601.  
  602.  
  603.     // FIXME. As above.
  604.     dest = ylookup[dc_yl] + columnofs[dc_x << 1]; 
  605.     dest2 = ylookup[dc_yl] + columnofs[(dc_x << 1) + 1];
  606.  
  607.     // Looks familiar.
  608.     fracstep = dc_iscale; 
  609.     frac = dc_texturemid + (dc_yl-centery)*fracstep; 
  610.  
  611.     // Here we do an additional index re-mapping.
  612.     do 
  613.     {
  614.     // Translation tables are used
  615.     //  to map certain colorramps to other ones,
  616.     //  used with PLAY sprites.
  617.     // Thus the "green" ramp of the player 0 sprite
  618.     //  is mapped to gray, red, black/indigo. 
  619.     *dest2 = *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]];
  620.     dest += SCREENWIDTH;
  621.     dest2 += SCREENWIDTH;
  622.     
  623.     frac += fracstep; 
  624.     } while (count--); 
  625.  
  626. //#endif
  627.  
  628.  
  629.  
  630. //
  631. // R_InitTranslationTables
  632. // Creates the translation tables to map
  633. //  the green color ramp to gray, brown, red.
  634. // Assumes a given structure of the PLAYPAL.
  635. // Could be read from a lump instead.
  636. //
  637. void R_InitTranslationTables (void)
  638. {
  639.     int        i;
  640.     
  641.     translationtables = Z_Malloc (256*3+255, PU_STATIC, 0);
  642.     translationtables = (byte *)(( (int)translationtables + 255 )& ~255);
  643.     
  644.     // translate just the 16 green colors
  645.     for (i=0 ; i<256 ; i++)
  646.     {
  647.     if (i >= 0x70 && i<= 0x7f)
  648.     {
  649.         // map green ramp to gray, brown, red
  650.         translationtables[i] = 0x60 + (i&0xf);
  651.         translationtables [i+256] = 0x40 + (i&0xf);
  652.         translationtables [i+512] = 0x20 + (i&0xf);
  653.     }
  654.     else
  655.     {
  656.         // Keep all other colors as is.
  657.         translationtables[i] = translationtables[i+256] 
  658.         = translationtables[i+512] = i;
  659.     }
  660.     }
  661. }
  662.  
  663.  
  664.  
  665.  
  666. //
  667. // R_DrawSpan 
  668. // With DOOM style restrictions on view orientation,
  669. //  the floors and ceilings consist of horizontal slices
  670. //  or spans with constant z depth.
  671. // However, rotation around the world z axis is possible,
  672. //  thus this mapping, while simpler and faster than
  673. //  perspective correct texture mapping, has to traverse
  674. //  the texture at an angle in all but a few cases.
  675. // In consequence, flats are not stored by column (like walls),
  676. //  and the inner loop has to step in texture space u and v.
  677. //
  678. int            ds_y; 
  679. int            ds_x1; 
  680. int            ds_x2;
  681.  
  682. lighttable_t*        ds_colormap; 
  683.  
  684. fixed_t            ds_xfrac; 
  685. fixed_t            ds_yfrac; 
  686. fixed_t            ds_xstep; 
  687. fixed_t            ds_ystep;
  688.  
  689. // start of a 64*64 tile image 
  690. byte*            ds_source;    
  691.  
  692. // just for profiling
  693. int            dscount;
  694.  
  695.  
  696. //
  697. // Draws the actual span.
  698. // UNUSED.
  699. #ifndef AMIGA
  700. void R_DrawSpan (void) 
  701.     fixed_t        xfrac;
  702.     fixed_t        yfrac; 
  703.     byte*        dest; 
  704.     int            count;
  705.     int            spot; 
  706.      
  707. #ifdef RANGECHECK 
  708.     if (ds_x2 < ds_x1
  709.     || ds_x1<0
  710.     || ds_x2>=SCREENWIDTH  
  711.     || (unsigned)ds_y>SCREENHEIGHT)
  712.     {
  713.     I_Error( "R_DrawSpan: %i to %i at %i",
  714.          ds_x1,ds_x2,ds_y);
  715.     }
  716. //    dscount++; 
  717. #endif 
  718.  
  719.     
  720.     xfrac = ds_xfrac; 
  721.     yfrac = ds_yfrac; 
  722.      
  723.     dest = ylookup[ds_y] + columnofs[ds_x1];
  724.  
  725.     // We do not check for zero spans here?
  726.     count = ds_x2 - ds_x1; 
  727.  
  728.     do 
  729.     {
  730.     // Current texture index in u,v.
  731.     spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  732.  
  733.     // Lookup pixel from flat texture tile,
  734.     //  re-index using light/colormap.
  735.     *dest++ = ds_colormap[ds_source[spot]];
  736.  
  737.     // Next step in u,v.
  738.     xfrac += ds_xstep; 
  739.     yfrac += ds_ystep;
  740.     
  741.     } while (count--); 
  742. #endif
  743.  
  744.  
  745.  
  746. // UNUSED.
  747. // Loop unrolled by 4.
  748. #if 0
  749. void R_DrawSpan (void) 
  750.     unsigned    position, step;
  751.  
  752.     byte*    source;
  753.     byte*    colormap;
  754.     byte*    dest;
  755.     
  756.     unsigned    count;
  757.     usingned    spot; 
  758.     unsigned    value;
  759.     unsigned    temp;
  760.     unsigned    xtemp;
  761.     unsigned    ytemp;
  762.         
  763.     position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff);
  764.     step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff);
  765.         
  766.     source = ds_source;
  767.     colormap = ds_colormap;
  768.     dest = ylookup[ds_y] + columnofs[ds_x1];     
  769.     count = ds_x2 - ds_x1 + 1; 
  770.     
  771.     while (count >= 4) 
  772.     { 
  773.     ytemp = position>>4;
  774.     ytemp = ytemp & 4032;
  775.     xtemp = position>>26;
  776.     spot = xtemp | ytemp;
  777.     position += step;
  778.     dest[0] = colormap[source[spot]]; 
  779.  
  780.     ytemp = position>>4;
  781.     ytemp = ytemp & 4032;
  782.     xtemp = position>>26;
  783.     spot = xtemp | ytemp;
  784.     position += step;
  785.     dest[1] = colormap[source[spot]];
  786.     
  787.     ytemp = position>>4;
  788.     ytemp = ytemp & 4032;
  789.     xtemp = position>>26;
  790.     spot = xtemp | ytemp;
  791.     position += step;
  792.     dest[2] = colormap[source[spot]];
  793.     
  794.     ytemp = position>>4;
  795.     ytemp = ytemp & 4032;
  796.     xtemp = position>>26;
  797.     spot = xtemp | ytemp;
  798.     position += step;
  799.     dest[3] = colormap[source[spot]]; 
  800.         
  801.     count -= 4;
  802.     dest += 4;
  803.     } 
  804.     while (count > 0) 
  805.     { 
  806.     ytemp = position>>4;
  807.     ytemp = ytemp & 4032;
  808.     xtemp = position>>26;
  809.     spot = xtemp | ytemp;
  810.     position += step;
  811.     *dest++ = colormap[source[spot]]; 
  812.     count--;
  813.     } 
  814. #endif
  815.  
  816.  
  817. #ifndef AMIGA
  818. //
  819. // Again..
  820. //
  821. void R_DrawSpanLow (void) 
  822.     fixed_t        xfrac;
  823.     fixed_t        yfrac; 
  824.     byte*        dest; 
  825.     int            count;
  826.     int            spot; 
  827.      
  828. #ifdef RANGECHECK 
  829.     if (ds_x2 < ds_x1
  830.     || ds_x1<0
  831.     || ds_x2>=SCREENWIDTH  
  832.     || (unsigned)ds_y>SCREENHEIGHT)
  833.     {
  834.     I_Error( "R_DrawSpan: %i to %i at %i",
  835.          ds_x1,ds_x2,ds_y);
  836.     }
  837. //    dscount++; 
  838. #endif 
  839.      
  840.     xfrac = ds_xfrac; 
  841.     yfrac = ds_yfrac; 
  842.  
  843.     // Blocky mode, need to multiply by 2.
  844.     ds_x1 <<= 1;
  845.     ds_x2 <<= 1;
  846.     
  847.     dest = ylookup[ds_y] + columnofs[ds_x1];
  848.   
  849.     
  850.     count = ds_x2 - ds_x1; 
  851.     do 
  852.     { 
  853.     spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
  854.     // Lowres/blocky mode does it twice,
  855.     //  while scale is adjusted appropriately.
  856.     *dest++ = ds_colormap[ds_source[spot]]; 
  857.     *dest++ = ds_colormap[ds_source[spot]];
  858.     
  859.     xfrac += ds_xstep; 
  860.     yfrac += ds_ystep; 
  861.  
  862.     } while (count--); 
  863. }
  864. #endif
  865.  
  866. //
  867. // R_InitBuffer 
  868. // Creats lookup tables that avoid
  869. //  multiplies and other hazzles
  870. //  for getting the framebuffer address
  871. //  of a pixel to draw.
  872. //
  873. void
  874. R_InitBuffer
  875. ( int        width,
  876.   int        height ) 
  877.     int        i; 
  878.  
  879.     // Handle resize,
  880.     //  e.g. smaller view windows
  881.     //  with border and/or status bar.
  882.     viewwindowx = (SCREENWIDTH-width) >> 1; 
  883.  
  884.     // Column offset. For windows.
  885.     for (i=0 ; i<width ; i++) 
  886.     columnofs[i] = viewwindowx + i;
  887.  
  888.     // Samw with base row offset.
  889.     if (width == SCREENWIDTH) 
  890.     viewwindowy = 0; 
  891.     else 
  892.     viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; 
  893.  
  894.     // Preclaculate all row offsets.
  895.     for (i=0 ; i<height ; i++) 
  896.     ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH; 
  897.  
  898.  
  899.  
  900.  
  901. //
  902. // R_FillBackScreen
  903. // Fills the back screen with a pattern
  904. //  for variable screen sizes
  905. // Also draws a beveled edge.
  906. //
  907. void R_FillBackScreen (void) 
  908.     byte*    src;
  909.     byte*    dest; 
  910.     int        x;
  911.     int        y; 
  912.     patch_t*    patch;
  913.  
  914.     // DOOM border patch.
  915.     char    name1[] = "FLOOR7_2";
  916.  
  917.     // DOOM II border patch.
  918.     char    name2[] = "GRNROCK";    
  919.  
  920.     char*    name;
  921.     
  922.     if (scaledviewwidth == 320)
  923.     return;
  924.     
  925.     if ( gamemode == commercial)
  926.     name = name2;
  927.     else
  928.     name = name1;
  929.     
  930.     src = W_CacheLumpName (name, PU_CACHE); 
  931.     dest = screens[1]; 
  932.      
  933.     for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) 
  934.     { 
  935.     for (x=0 ; x<SCREENWIDTH/64 ; x++) 
  936.     { 
  937.         memcpy (dest, src+((y&63)<<6), 64); 
  938.         dest += 64; 
  939.     } 
  940.  
  941.     if (SCREENWIDTH&63) 
  942.     { 
  943.         memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); 
  944.         dest += (SCREENWIDTH&63); 
  945.     } 
  946.     } 
  947.     
  948.     patch = W_CacheLumpName ("brdr_t",PU_CACHE);
  949.  
  950.     for (x=0 ; x<scaledviewwidth ; x+=8)
  951.     V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch);
  952.     patch = W_CacheLumpName ("brdr_b",PU_CACHE);
  953.  
  954.     for (x=0 ; x<scaledviewwidth ; x+=8)
  955.     V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch);
  956.     patch = W_CacheLumpName ("brdr_l",PU_CACHE);
  957.  
  958.     for (y=0 ; y<viewheight ; y+=8)
  959.     V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch);
  960.     patch = W_CacheLumpName ("brdr_r",PU_CACHE);
  961.  
  962.     for (y=0 ; y<viewheight ; y+=8)
  963.     V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch);
  964.  
  965.  
  966.     // Draw beveled edge. 
  967.     V_DrawPatch (viewwindowx-8,
  968.          viewwindowy-8,
  969.          1,
  970.          W_CacheLumpName ("brdr_tl",PU_CACHE));
  971.     
  972.     V_DrawPatch (viewwindowx+scaledviewwidth,
  973.          viewwindowy-8,
  974.          1,
  975.          W_CacheLumpName ("brdr_tr",PU_CACHE));
  976.     
  977.     V_DrawPatch (viewwindowx-8,
  978.          viewwindowy+viewheight,
  979.          1,
  980.          W_CacheLumpName ("brdr_bl",PU_CACHE));
  981.     
  982.     V_DrawPatch (viewwindowx+scaledviewwidth,
  983.          viewwindowy+viewheight,
  984.          1,
  985.          W_CacheLumpName ("brdr_br",PU_CACHE));
  986.  
  987.  
  988. //
  989. // Copy a screen buffer.
  990. //
  991. void
  992. R_VideoErase
  993. ( unsigned    ofs,
  994.   int        count ) 
  995.   // LFB copy.
  996.   // This might not be a good idea if memcpy
  997.   //  is not optiomal, e.g. byte by byte on
  998.   //  a 32bit CPU, as GNU GCC/Linux libc did
  999.   //  at one point.
  1000.     memcpy (screens[0]+ofs, screens[1]+ofs, count); 
  1001.  
  1002.  
  1003. //
  1004. // R_DrawViewBorder
  1005. // Draws the border around the view
  1006. //  for different size windows?
  1007. //
  1008. void
  1009. V_MarkRect
  1010. ( int        x,
  1011.   int        y,
  1012.   int        width,
  1013.   int        height ); 
  1014.  
  1015. void R_DrawViewBorder (void) 
  1016.     int        top;
  1017.     int        side;
  1018.     int        ofs;
  1019.     int        i; 
  1020.  
  1021.     if (scaledviewwidth == SCREENWIDTH) 
  1022.     return; 
  1023.   
  1024.     top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2; 
  1025.     side = (SCREENWIDTH-scaledviewwidth)/2; 
  1026.  
  1027.     // copy top and one line of left side 
  1028.     R_VideoErase (0, top*SCREENWIDTH+side); 
  1029.  
  1030.     // copy one line of right side and bottom 
  1031.     ofs = (viewheight+top)*SCREENWIDTH-side; 
  1032.     R_VideoErase (ofs, top*SCREENWIDTH+side); 
  1033.  
  1034.     // copy sides using wraparound 
  1035.     ofs = top*SCREENWIDTH + SCREENWIDTH-side; 
  1036.     side <<= 1;
  1037.     
  1038.     for (i=1 ; i<viewheight ; i++) 
  1039.     { 
  1040.     R_VideoErase (ofs, side); 
  1041.     ofs += SCREENWIDTH; 
  1042.     } 
  1043.  
  1044.     // ? 
  1045.     V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT); 
  1046.  
  1047.  
  1048.